﻿using System;
using SLNGP.Common.IoC;
using SLNGP.Core.GeneticPrograms;
using SLNGP.Core.Individuals;
using SLNGP.Core.SecondaryStrategies;

namespace SLNGP.Core.Initialization
{
    /// <summary>
    /// Sample Initialization strategy that only initializes the root gene of an individual.
    /// This sample is a super simple case of the "Full 1" case meant for testing. 
    /// </summary>
    public class OnlyRootNodeInitialization : IFirstGenerationInitialization
    {
        public OnlyRootNodeInitialization(int numberOfInitializedIndividuals, IGeneticProgram parent)
        {
            NumberOfInitializedIndividuals = numberOfInitializedIndividuals;
            Parent = parent;
        }

        public int NumberOfInitializedIndividuals { get; set; }

        public IGeneration GetFirstGeneration()
        {
            IGeneration generation = IoC.Get<IGeneration>();
            for (int i = 0; i < NumberOfInitializedIndividuals; i++)
            {
                IIndividual NewIndividual = IoC.Get<IIndividual>();
                NewIndividual.ParentGeneticProgram = Parent;
                NewIndividual.Chromosome.RootGene = 
                    Parent.GetStrategy<ISelectRandomGeneDefinition>().SelectRandomDefinition().Create();
                
                if (!NewIndividual.IsValid)
                {
                    NewIndividual.Fix();
                }

                if (!generation.ContainsIndividualWithSameGenome(NewIndividual))
                    generation.Add(NewIndividual);
                else
                    i = i - 1;
            }
            return generation;
        }

        public IGeneticProgram Parent { get; set; }
    }
}